using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace Lazeeboy.FantomG
{
    class RPSSet
    {
        private static List<RPSSet> _rpsSets;

        static RPSSet()
        {
            InitializeRPSSetList();
        }

        private static void InitializeRPSSetList()
        {
            _rpsSets = new List<RPSSet>();

            for (Int16 i = 1; i <= 64; i++)
                _rpsSets.Add(new RPSSet(i));
        }

        public static List<RPSSet> RPSSets
        { get { return _rpsSets; } }

        private static string _projectPath;

        private static string PhraseSetsPath
        { get { return System.IO.Path.Combine(_projectPath, string.Format(@"SEQ{0}RPS{0}", System.IO.Path.DirectorySeparatorChar)); } }

        public static void Load(string ProjectPath)
        {
            _projectPath = ProjectPath;

            if (Directory.Exists(PhraseSetsPath) && Directory.Exists(PhraseSetsPath))
            {
                string[] rpsFiles = Directory.GetFiles(PhraseSetsPath, "*RPS.BIN");

                if (rpsFiles != null && rpsFiles.GetUpperBound(0) >= 0)
                {
                    Encoding encoding = Encoding.ASCII;

                    for (int i = 0; i <= rpsFiles.GetUpperBound(0); i++)
                    {
                        string rpsFileName = System.IO.Path.GetFileNameWithoutExtension(rpsFiles[i]);

                        Int16 rpsPosition;

                        if (Int16.TryParse(rpsFileName.Substring(0, 3), out rpsPosition) && rpsPosition > 0 && rpsPosition <= 64)
                        {
                            FileStream rpsStream = File.OpenRead(rpsFiles[i]);
                            byte[] rpsNameBytes = new byte[16];
                            rpsStream.Position = 0x10;
                            rpsStream.Read(rpsNameBytes, 0, 16);

                            string rpsName = encoding.GetString(rpsNameBytes);

                            AddRPSSet(rpsPosition, rpsName, rpsFiles[i]);
                        }
                    }
                }
            }
        }
		
		public static void Save(string ProjectPath)
		{
			if(ProjectPath == _projectPath && Directory.Exists(PhraseSetsPath))
            {
				int phraseSetPosition;
                foreach (string file in Directory.GetFiles(PhraseSetsPath, "*RPS.BIN"))
                {
                    string phraseSetFileName = System.IO.Path.GetFileNameWithoutExtension(file);
                    if (Int32.TryParse(phraseSetFileName, out phraseSetPosition) && phraseSetPosition > 0 && phrasePosition <= 64)
                        File.Delete(file);
                }

				foreach(RPSSet rpsSet in _rpsSets)
				{
					if (rpsSet._bytesChanged)
                    {
                        File.WriteAllBytes(rpsSet._path, rpsSet._bytes);

                        if(!rpsSet._wasOriginallyFile && rpsSet._isFile)
						{
							// todo: rpsset was created so save it
						}
						else if(rpsSet._wasOriginallyFile && rpsSet._isFile)
						{
							// todo: rpsset was overwritten so save it
							
							// todo: delete references to the rpsset in all livesets
						}
                    }
                    else if (phrase._isFile)
                    {
//                        if (phrase._originalName != phrase._name)
//                        {
//                            byte[] nameAsBytes = encoding.GetBytes(phrase._name);
//                            byte[] nameAs15Bytes = new byte[15];
//                            if (nameAsBytes.GetUpperBound(0) >= 0)
//                            {
//                                Array.Copy(nameAsBytes, 0, nameAs15Bytes, 0, nameAsBytes.GetUpperBound(0) + 1);
//                                Array.Copy(nameAs15Bytes, 0, phrase._bytes, 14, 15);
//
//                                sbUpdatesMade.AppendLine(string.Format("Phrase number {0:0000} was renamed from '{1}' to '{2}'",
//                                    phrase._originalPosition, phrase._originalName.Trim(), phrase._name.Trim()));
//                            }
//                        }
                        if (phrase._originalPosition != phrase._position)
                        {
                            sbUpdatesMade.AppendLine(string.Format("Phrase number {0:0000} was moved to {1:0000}",
                                phrase._originalPosition, phrase._position));

                            phrase._path = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(phrase._path), 
                                string.Format("{0:0000}.SVP", phrase._position));
							
							// todo: phrase was moved so update references to it in livesets
							
							// todo: phrase was moved so update references to it in rpssets
                        }

                        if (phrase._wasOriginallyFile && !phrase._isFile)
                        {
							// todo: phrase was deleted so remove all references to it in the livesets
							
							// todo: phrase was deleted so remove all references to it in rpssets
							
                            sbUpdatesMade.AppendLine(string.Format("Phrase number {0:0000} was deleted.",
                                phrase._originalPosition));
                        }

                        File.WriteAllBytes(phrase._path, phrase._bytes);
                    }
				}
			}
		}

        public static void AddRPSSet(short Position, string Name, string Path)
        {
            _rpsSets[Position - 1] = new RPSSet(Position, Name, Path);
        }

        public static RPSSet FindByPosition(short Position)
        {
            if(RPSSets != null && RPSSets.Count > 0)
                foreach(RPSSet rpsSet in RPSSets)
                    if(rpsSet.Position == Position)
                        return rpsSet;

            return null;
        }

        private Int16 _position;
        private Int16 _originalPosition;
		private bool _isFile;
        private bool _wasOriginallyFile;
		private string _originalName;
        private string _name;
        private string _path;
		private byte[] _bytes;
		private bool _bytesChanged;
		
        private RPSSet(short Position)
        {
            _position = Position;
            _originalPosition = Position;
            _originalName = "(---)";
            _name = _originalName;
            _path = "";
        }

        private RPSSet(short Position, string Name, string Path)
        {
            _position = Position;
            _originalPosition = Position;
            _name = Name;
            _originalName = Name;
            _path = Path;
			
			try { _bytes = File.ReadAllBytes(Path); }
			catch {}
        }

        public string Name
        { get { return _name; } }

        public short Position
        {
            get { return _position; }
            set { _position = value; }
        }

		public bool IsFile
        { get { return _isFile; } }
		
        public int OriginalPosition
        { get { return _originalPosition; } }

        public string OriginalName
        { get { return _originalName; } }

        public string Path
        { get { return _path; } }

		public byte[] Bytes
		{ get { return _bytes; } }
		
        public override string ToString()
        {
            bool Changed = (_name != OriginalName || _position != _originalPosition || _isFile != _wasOriginallyFile || _bytesChanged );

            return string.Format("{0:00}: {1} {2}",
                _position, Changed ? "*" : "", _name);
        }


    }
}
